package com.fumasoft.dynamic.utils;

import java.io.*;
import java.nio.file.Files;
import java.util.*;
import org.springframework.util.ResourceUtils;

/**
 * 中文转换.
 *
 * @author jingchen
 * @date 2025/08/30
 */
public class ZHConverter {
    private Properties charMap = new Properties();

    private Set<String> conflictingSets = new HashSet<String>();

    /**
     * 0 for traditional and 1 for simplified.
     */
    public static final int TRADITIONAL = 0;

    /**
     * 0 for traditional and 1 for simplified.
     */
    public static final int SIMPLIFIED = 1;

    /**
     * number of converters.
     */
    private static final int NUM_OF_CONVERTERS = 2;

    /**
     * converters.
     */
    private static final ZHConverter[] CONVERTERS = new ZHConverter[NUM_OF_CONVERTERS];

    /**
     * property files.
     */
    private static final String[] PROPERTYFILES = new String[NUM_OF_CONVERTERS];

    static {
        PROPERTYFILES[TRADITIONAL] = "zh2Hant.properties"; //附件下载
        PROPERTYFILES[SIMPLIFIED] = "zh2Hans.properties";  //附件下载
    }

    /**
     * 获取转换器.
     *
     * @param converterType 0 for traditional and 1 for simplified
     * @return 转换器
     */
    public static ZHConverter getInstance(int converterType) {
        if (converterType >= 0 && converterType < NUM_OF_CONVERTERS) {
            if (CONVERTERS[converterType] == null) {
                synchronized (ZHConverter.class) {
                    if (CONVERTERS[converterType] == null) {
                        CONVERTERS[converterType] = new ZHConverter(PROPERTYFILES[converterType]);
                    }
                }
            }
            return CONVERTERS[converterType];
        } else {
            return null;
        }
    }


    /**
     * 构造函数.
     *
     * @param propertyFile property file
     */
    private ZHConverter(String propertyFile) {
        InputStream is = null;
        String path = "";

        try {
            File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + propertyFile);
            is = Files.newInputStream(file.toPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (is != null) {
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(is));
                charMap.load(reader);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        initializeHelper();
    }

    /**
     * 初始化辅助.
     */
    @SuppressWarnings("rawtypes")
    private void initializeHelper() {
        Map<String, Integer> stringPossibilities = new HashMap<String, Integer>();
        Iterator iter = charMap.keySet().iterator();
        while (iter.hasNext()) {
            String key = (String) iter.next();
            if (key.length() >= 1) {
                for (int i = 0; i < (key.length()); i++) {
                    String keySubstring = key.substring(0, i + 1);
                    if (stringPossibilities.containsKey(keySubstring)) {
                        Integer integer = (Integer) (stringPossibilities.get(keySubstring));
                        stringPossibilities.put(keySubstring, new Integer(
                                integer.intValue() + 1));
                    } else {
                        stringPossibilities.put(keySubstring, new Integer(1));
                    }
                }
            }
        }
        iter = stringPossibilities.keySet().iterator();
        while (iter.hasNext()) {
            String key = (String) iter.next();
            if (((Integer) (stringPossibilities.get(key))).intValue() > 1) {
                conflictingSets.add(key);
            }
        }
    }

    /**
     * 转换.
     *
     * @param in 输入
     * @return 转换后的文本
     */
    public String convert(String in) {
        StringBuilder outString = new StringBuilder();
        StringBuilder stackString = new StringBuilder();
        for (int i = 0; i < in.length(); i++) {
            char c = in.charAt(i);
            String key = "" + c;
            stackString.append(key);
            if (charMap.containsKey(stackString.toString())) {
                outString.append(charMap.get(stackString.toString()));
                stackString.setLength(0);
            } else {
                CharSequence sequence = stackString.subSequence(0, stackString.length() - 1);
                stackString.delete(0, stackString.length() - 1);
                flushStack(outString, new StringBuilder(sequence));
            }
        }
        flushStack(outString, stackString);
        return outString.toString();
    }

    /**
     * 刷新栈.
     *
     * @param outString 输出
     * @param stackString 栈
     */
    private void flushStack(StringBuilder outString, StringBuilder stackString) {
        while (stackString.length() > 0) {
            if (charMap.containsKey(stackString.toString())) {
                outString.append(charMap.get(stackString.toString()));
                stackString.setLength(0);
            } else {
                outString.append("" + stackString.charAt(0));
                stackString.delete(0, 1);
            }
        }
    }

    /**
     * 解析一个字符.
     *
     * @param c 字符
     * @return 解析后的字符
     */
    String parseOneChar(String c) {
        if (charMap.containsKey(c)) {
            return (String) charMap.get(c);

        }
        return c;
    }
}
